package git.soulbgm.socket;

import git.soulbgm.utils.LogUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;

import java.net.InetSocketAddress;

/**
 * TCP协议消息处理类
 *
 * @author SoulBGM
 * @date 2021-03-29
 */
@ChannelHandler.Sharable
public class TcpServerHandler extends SimpleChannelInboundHandler<ByteBuf> {

    private final LogUtil log = new LogUtil(getClass());

    private static final byte[] HEARTBEAT_PACK = {-27, -65, -125, -24, -73, -77};

    /**
     * 当客户端连接上来时调用
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        InetSocketAddress address = (InetSocketAddress) channel.remoteAddress();
        String ip = address.getAddress().getHostAddress();
        TcpConnection.put(channel);
        int localPort = getLocalPort(ctx);
        log.info("TCP客户端 {} 连接服务器 {} 端口成功", ip, localPort);
    }


    /**
     * 当客户端连接断开时调用
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Integer localPort = getLocalPort(ctx);
        Channel channel = ctx.channel();
        InetSocketAddress address = (InetSocketAddress) channel.remoteAddress();
        String ip = address.getAddress().getHostAddress();
        TcpConnection.remove(channel);
        log.warn("TCP客户端 {} 断开服务器 {} 端口连接", ip, localPort);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {

    }

    /**
     * 用户事件触发
     *
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
    }

    /**
     * 获得客户端连接的本地端口
     */
    private int getLocalPort(ChannelHandlerContext ctx) {
        String host = ctx.channel().localAddress().toString();
        return Integer.parseInt(host.substring(host.indexOf(":") + 1));
    }

    /**
     * 过滤数据,包括空数据和心跳包
     *
     * @param data 数据
     * @return 返回true是心跳包 false不是
     */
    private boolean isHeartbeatData(byte[] data) {
        if (data != null && data.length == HEARTBEAT_PACK.length) {
            if (byteArrayEquals(data, HEARTBEAT_PACK)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 比较两个byte数组
     *
     * @param b1 第一个byte数组
     * @param b2 第二个byte数组
     * @return 相等返回true 否则false
     */
    public static boolean byteArrayEquals(byte[] b1, byte[] b2) {
        if (b1 == null || b2 == null) {
            return false;
        }

        if (b1.length != b2.length) {
            return false;
        }

        boolean isEqual = true;
        for (int i = 0; i < b1.length; i++) {
            if (b1[i] != b2[i]) {
                isEqual = false;
                break;
            }
        }
        return isEqual;
    }

}
